<html>
    <head>
    <link rel="stylesheet" href="lmm.css" type="text/css" />
    </head>
<body class="lmm">
<!-- This file is part of the Lisp Machine manual.	-*-Text-*- -->

<div class='chapter' id='18'>18. The Compiler</div><p class='cindent' id='compiler'><!-- compiler -->
<div class='section' id='18.1'>18.1 The Basic Operations of the Compiler</div>
	The purpose of the Lisp compiler is to convert Lisp functions
into programs in the Lisp Machine's instruction set, so that they
will run more quickly and take up less storage.  Compiled functions
are represented in Lisp by FEFs (Function
Entry Frames), which contain machine code as well as various other information.
The format of FEFs and the instruction set are explained in <font color='red'>LINK:(</font>section-fef-format).

	There are three ways to invoke the compiler from the Lisp
Machine.  First, you may have an interpreted function in the Lisp
environment which you would like to compile.  The function <!-- open: 1, close: 0 --><font class="lisp">compile</font><!-- open: 1, close: 1 --> <!-- MATCHED MATCHED MATCHED -->
is used to do this.  Second, you may have code in an editor buffer
which you would like to compile.  The EINE editor has commands
to read code into Lisp and compile it.
Third, you may have a program (a of function definitions and other forms) written in a
file on the file system.  The compiler can translate this file into a
QFASL file.  Loading in the QFASL file is like reading in the source
file, except that the functions in the source file will be compiled.
The <!-- open: 2, close: 1 --><font class="lisp">qc-file</font><!-- open: 2, close: 2 --> <!-- MATCHED MATCHED MATCHED --> function is used for translating source files into QFASL files.

<!-- Explain why the compiler expands macros. -->
<!-- Explain specialness versus localness, etc. -->

<div class='section' id='18.2'>18.2 How to Invoke the Compiler</div>
<div class='defun' id='compile'>
  <font class='exdent'>
    <font class='funcname'>compile </font>
    <font class='italic' color='purple'>symbol</font>
  </font><br>
<!-- open: 3, close: 2 --><font class="italic">symbol</font><!-- open: 3, close: 3 --> <!-- MATCHED MATCHED MATCHED --> should be defined as an interpreted function (its definition
should be a lambda-expression).  The compiler converts the lambda-expression
into a FEF, saves the lambda-expression as the <!-- open: 4, close: 3 --><font class="lisp">:previous-expr-definition</font><!-- open: 4, close: 4 --> <!-- MATCHED MATCHED MATCHED -->
and <!-- open: 5, close: 4 --><font class="lisp">:previous-definition</font><!-- open: 5, close: 5 --> <!-- MATCHED MATCHED MATCHED --> properties of <!-- open: 6, close: 5 --><font class="italic">symbol</font><!-- open: 6, close: 6 --> <!-- MATCHED MATCHED MATCHED -->, and changes <!-- open: 7, close: 6 --><font class="italic">symbol</font><!-- open: 7, close: 7 --> <!-- MATCHED MATCHED MATCHED -->'s
definition to be the FEF.  (See <!-- open: 8, close: 7 --><font class="lisp">fset-carefully</font><!-- open: 8, close: 8 --> <!-- MATCHED MATCHED MATCHED -->, <font color='red'>LINK:(</font>fset-carefully-fun).
(Actually, if <!-- open: 9, close: 8 --><font class="italic">symbol</font><!-- open: 9, close: 9 --> <!-- MATCHED MATCHED MATCHED --> is not defined as a lambda-expression,
<!-- open: 10, close: 9 --><font class="lisp">compile</font><!-- open: 10, close: 10 --> <!-- MATCHED MATCHED MATCHED --> will try to find a lambda-expression in the <!-- open: 11, close: 10 --><font class="lisp">:previous-expr-definition</font><!-- open: 11, close: 11 --> <!-- MATCHED MATCHED MATCHED -->
property of <!-- open: 12, close: 11 --><font class="italic">symbol</font><!-- open: 12, close: 12 --> <!-- MATCHED MATCHED MATCHED --> and use that instead.)
</div>

<div class='defun' id='uncompile'>
  <font class='exdent'>
    <font class='funcname'>uncompile </font>
    <font class='italic' color='purple'>symbol</font>
  </font><br>
If <!-- open: 13, close: 12 --><font class="italic">symbol</font><!-- open: 13, close: 13 --> <!-- MATCHED MATCHED MATCHED --> is not defined as an interpreted function and it
has a <!-- open: 14, close: 13 --><font class="lisp">:previous-expr-definition</font><!-- open: 14, close: 14 --> <!-- MATCHED MATCHED MATCHED --> property, then <!-- open: 15, close: 14 --><font class="lisp">uncompile</font><!-- open: 15, close: 15 --> <!-- MATCHED MATCHED MATCHED -->
will restore the function cell from the value of the property.
This "undoes" the effect of <!-- open: 16, close: 15 --><font class="lisp">compile</font><!-- open: 16, close: 16 --> <!-- MATCHED MATCHED MATCHED -->.
</div>

<div class='defun' id='qc-file'>
  <font class='exdent'>
    <font class='funcname'>qc-file </font>
    <font class='italic' color='purple'>filename &optional output-file load-flag in-core-flag package</font>
  </font><br>
The file <!-- open: 17, close: 16 --><font class="italic">filename</font><!-- open: 17, close: 17 --> <!-- MATCHED MATCHED MATCHED --> is given to the compiler, and the output of the
compiler is written to a file whose name is <!-- open: 18, close: 17 --><font class="italic">filename</font><!-- open: 18, close: 18 --> <!-- MATCHED MATCHED MATCHED --> except with an
FN2 of "QFASL".  The input format for files to the compiler is
described on <a href='compil.html#compiler-input-section'>this link</a>.
Macro definitions and <!-- open: 19, close: 18 --><font class="lisp">special</font><!-- open: 19, close: 19 --> <!-- MATCHED MATCHED MATCHED --> declarations created during
the compilation will be undone when the compilation is
finished.

The optional arguments allow certain modifications to this procedure.
<!-- open: 20, close: 19 --><font class="italic">output-file</font><!-- open: 20, close: 20 --> <!-- MATCHED MATCHED MATCHED --> lets you change where the output is written.
<!-- open: 21, close: 20 --><font class="italic">package</font><!-- open: 21, close: 21 --> <!-- MATCHED MATCHED MATCHED --> lets you specify in what package the source file is to
be read.  Normally the system knows, or asks interactively,
and you need not supply this argument.
<!-- open: 22, close: 21 --><font class="italic">load-flag</font><!-- open: 22, close: 22 --> <!-- MATCHED MATCHED MATCHED --> and <!-- open: 23, close: 22 --><font class="italic">in-core-flag</font><!-- open: 23, close: 23 --> <!-- MATCHED MATCHED MATCHED --> are incomprehensible; you don't
want to use them.
</div>

<div class='defun' id='qc-file-load'>
  <font class='exdent'>
    <font class='funcname'>qc-file-load </font>
    <font class='italic' color='purple'>filename</font>
  </font><br>
<!-- open: 24, close: 23 --><font class="lisp">qc-file-load</font><!-- open: 24, close: 24 --> <!-- MATCHED MATCHED MATCHED --> compiles a file and then loads it in.
</div>

See also the <!-- open: 25, close: 24 --><font class="lisp">disassemble</font><!-- open: 25, close: 25 --> <!-- MATCHED MATCHED MATCHED --> function (<font color='red'>LINK:(</font>disassemble-fun)), which lists the instructions
of a compiled function in symbolic form.


	The compiler can also be run in Maclisp on ITS.  On the MIT-AI
machine, type :LISPM1;QCMP.  It will type out "READY" and leave you
at a Maclisp top level.  Then type <!-- open: 26, close: 25 --><font class="lisp">(qc-file <!-- open: 27, close: 25 --><font class="italic">filename</font><!-- open: 27, close: 26 -->)</font><!-- open: 27, close: 27 --> <!-- MATCHED MATCHED MATCHED -->,
expressing <!-- open: 28, close: 27 --><font class="italic">filename</font><!-- open: 28, close: 28 --> <!-- MATCHED MATCHED MATCHED --> in Maclisp form.
<pre class='lisp'>
<font class='exdent'>Example:
</font><!-- exdent -->(qc-file '((lispm) foo &gt;))
</pre>

<div class='section' id='18.3'>18.3 Input to the Compiler</div><p class='cindent' id='compiler-input-section'><!-- input to the compiler -->
	The purpose of <!-- open: 29, close: 28 --><font class="lisp">qc-file</font><!-- open: 29, close: 29 --> <!-- MATCHED MATCHED MATCHED --> is to take a file and produce
a translated version which does the same thing as the original except
that the functions are compiled.  <!-- open: 30, close: 29 --><font class="lisp">qc-file</font><!-- open: 30, close: 30 --> <!-- MATCHED MATCHED MATCHED --> reads through the input
file, processing the forms in it one by one.  For each form, suitable
binary output is sent to the QFASL file so that when the QFASL file is
loaded the effect of that source form will be reproduced.  The differences
between source files and QFASL files are that QFASL files are in a compressed
binary form which reads much faster (but cannot be edited), and that
function definitions in QFASL files have been translated from S-expressions
to FEFs.

	So, if the source contains a <!-- open: 31, close: 30 --><font class="lisp">(defun ...)</font><!-- open: 31, close: 31 --> <!-- MATCHED MATCHED MATCHED --> form at top
level, then when the QFASL file is loaded, the function will be defined
as a compiled function.  If the source file contains a form which is
not of a type known specially to the compiler, then that form will be
output "directly" into the QFASL file, so that when the QFASL file is
loaded that form will be evaluated.  Thus, if the source file contains
<!-- open: 32, close: 31 --><font class="lisp">(setq x 3)</font><!-- open: 32, close: 32 --> <!-- MATCHED MATCHED MATCHED -->, then the compiler will put in the QFASL file
instructions to set <!-- open: 33, close: 32 --><font class="lisp">x</font><!-- open: 33, close: 33 --> <!-- MATCHED MATCHED MATCHED --> to <!-- open: 34, close: 33 --><font class="lisp">3</font><!-- open: 34, close: 34 --> <!-- MATCHED MATCHED MATCHED --> at load time.

	However, sometimes we want to put things in the file
that are not merely meant to be translated into QFASL form.
One such occasion is top level macro definitions; the macros
must actually get defined within the compiler in order that the
compiler be able to expand them at compile time.  So when a macro
form is seen, it should (sometimes) be evaluated at compile time,
and should (sometimes) be put into the QFASL file.

	Another thing we sometimes want to put in a file is
compiler declarations.  These are forms which should be evaluated
at compile time to tell the compiler something.  They should
not be put into the QFASL file.

	Therefore, a facility exists to allow the user to tell
the compiler just what to do with a form.  One might want a form
to be:
<table>
<tr valign='top'><td colspan='2'><font class='lisp'> Put into the QFASL file (translated), or not.</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td></td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> Evaluated within the compiler, or not.</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td></td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> Evaluated if the file is read directly into Lisp, or not.</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td></td></tr><!-- item_ --></table><!-- end table -->


	Two forms are recognized by the compiler to allow this.  The less
general but Maclisp compatible one is <!-- open: 35, close: 34 --><font class="lisp">declare</font><!-- open: 35, close: 35 --> <!-- MATCHED MATCHED MATCHED -->; the completely
general one is <!-- open: 36, close: 35 --><font class="lisp">eval-when</font><!-- open: 36, close: 36 --> <!-- MATCHED MATCHED MATCHED -->.

	An <!-- open: 37, close: 36 --><font class="lisp">eval-when</font><!-- open: 37, close: 37 --> <!-- MATCHED MATCHED MATCHED --> form looks like
<pre class='lisp'>
(eval-when <!-- open: 38, close: 37 --><font class="italic">times-list</font><!-- open: 38, close: 38 --> <!-- MATCHED MATCHED MATCHED -->
	   <!-- open: 39, close: 38 --><font class="italic">form1</font><!-- open: 39, close: 39 --> <!-- MATCHED MATCHED MATCHED -->
	   <!-- open: 40, close: 39 --><font class="italic">form2</font><!-- open: 40, close: 40 --> <!-- MATCHED MATCHED MATCHED -->
           ...)
</pre>
The <!-- open: 41, close: 40 --><font class="italic">times-list</font><!-- open: 41, close: 41 --> <!-- MATCHED MATCHED MATCHED --> may contain any of the symbols <!-- open: 42, close: 41 --><font class="lisp">load</font><!-- open: 42, close: 42 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 43, close: 42 --><font class="lisp">compile</font><!-- open: 43, close: 43 --> <!-- MATCHED MATCHED MATCHED -->,
or <!-- open: 44, close: 43 --><font class="lisp">eval</font><!-- open: 44, close: 44 --> <!-- MATCHED MATCHED MATCHED -->.
If <!-- open: 45, close: 44 --><font class="lisp">load</font><!-- open: 45, close: 45 --> <!-- MATCHED MATCHED MATCHED --> is present, the <!-- open: 46, close: 45 --><font class="italic">form</font><!-- open: 46, close: 46 --> <!-- MATCHED MATCHED MATCHED -->s are written into the QFASL file
to be evaluated when the QFASL file is loaded (except that <!-- open: 47, close: 46 --><font class="lisp">defun</font><!-- open: 47, close: 47 --> <!-- MATCHED MATCHED MATCHED --> forms
will put the compiled definition into the QFASL file instead).
If <!-- open: 48, close: 47 --><font class="lisp">compile</font><!-- open: 48, close: 48 --> <!-- MATCHED MATCHED MATCHED --> is present, the <!-- open: 49, close: 48 --><font class="italic">form</font><!-- open: 49, close: 49 --> <!-- MATCHED MATCHED MATCHED -->s are evaluated in the compiler.
If <!-- open: 50, close: 49 --><font class="lisp">eval</font><!-- open: 50, close: 50 --> <!-- MATCHED MATCHED MATCHED --> is present, the <!-- open: 51, close: 50 --><font class="italic">form</font><!-- open: 51, close: 51 --> <!-- MATCHED MATCHED MATCHED -->s are evaluated when read into Lisp;
this is because <!-- open: 52, close: 51 --><font class="lisp">eval-when</font><!-- open: 52, close: 52 --> <!-- MATCHED MATCHED MATCHED --> is defined as a special form in Lisp.  (The
compiler ignores <!-- open: 53, close: 52 --><font class="lisp">eval</font><!-- open: 53, close: 53 --> <!-- MATCHED MATCHED MATCHED --> in the <!-- open: 54, close: 53 --><font class="italic">times-list</font><!-- open: 54, close: 54 --> <!-- MATCHED MATCHED MATCHED -->.)
For example, <!-- open: 55, close: 54 --><font class="lisp">(eval-when (compile eval) (macro foo (x) (cadr x)))</font><!-- open: 55, close: 55 --> <!-- MATCHED MATCHED MATCHED -->
would define <!-- open: 56, close: 55 --><font class="lisp">foo</font><!-- open: 56, close: 56 --> <!-- MATCHED MATCHED MATCHED --> as a macro in the compiler and when the file
is read in interpreted, but not when the QFASL file is fasloaded.

	For the rest of this section, we will use lists such as are
given to <!-- open: 57, close: 56 --><font class="lisp">eval-when</font><!-- open: 57, close: 57 --> <!-- MATCHED MATCHED MATCHED -->, e.g. <!-- open: 58, close: 57 --><font class="lisp">(load eval)</font><!-- open: 58, close: 58 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 59, close: 58 --><font class="lisp">(load compile)</font><!-- open: 59, close: 59 --> <!-- MATCHED MATCHED MATCHED -->, etc.
to describe when forms are evaluated.

	A <!-- open: 60, close: 59 --><font class="lisp">declare</font><!-- open: 60, close: 60 --> <!-- MATCHED MATCHED MATCHED --> form looks like <!-- open: 61, close: 60 --><font class="lisp">(declare <!-- open: 62, close: 60 --><font class="italic">form1 form2</font><!-- open: 62, close: 61 --> ...)</font><!-- open: 62, close: 62 --> <!-- MATCHED MATCHED MATCHED -->.
<!-- open: 63, close: 62 --><font class="lisp">declare</font><!-- open: 63, close: 63 --> <!-- MATCHED MATCHED MATCHED --> is defined in Lisp as a special form which does nothing;
so the forms within a <!-- open: 64, close: 63 --><font class="lisp">declare</font><!-- open: 64, close: 64 --> <!-- MATCHED MATCHED MATCHED --> are not evaluated at <!-- open: 65, close: 64 --><font class="lisp">eval</font><!-- open: 65, close: 65 --> <!-- MATCHED MATCHED MATCHED --> time.
The compiler does the following upon finding <!-- open: 66, close: 65 --><font class="italic">form</font><!-- open: 66, close: 66 --> <!-- MATCHED MATCHED MATCHED --> within
a <!-- open: 67, close: 66 --><font class="lisp">declare</font><!-- open: 67, close: 67 --> <!-- MATCHED MATCHED MATCHED -->:  if <!-- open: 68, close: 67 --><font class="italic">form</font><!-- open: 68, close: 68 --> <!-- MATCHED MATCHED MATCHED --> is a call to either <!-- open: 69, close: 68 --><font class="lisp">special</font><!-- open: 69, close: 69 --> <!-- MATCHED MATCHED MATCHED -->
or <!-- open: 70, close: 69 --><font class="lisp">unspecial</font><!-- open: 70, close: 70 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 71, close: 70 --><font class="italic">form</font><!-- open: 71, close: 71 --> <!-- MATCHED MATCHED MATCHED --> is treated as <!-- open: 72, close: 71 --><font class="lisp">(load compile)</font><!-- open: 72, close: 72 --> <!-- MATCHED MATCHED MATCHED -->;
otherwise it is treated as <!-- open: 73, close: 72 --><font class="lisp">(compile)</font><!-- open: 73, close: 73 --> <!-- MATCHED MATCHED MATCHED -->.

	If a form is not enclosed in an <!-- open: 74, close: 73 --><font class="lisp">eval-when</font><!-- open: 74, close: 74 --> <!-- MATCHED MATCHED MATCHED --> nor a <!-- open: 75, close: 74 --><font class="lisp">declare</font><!-- open: 75, close: 75 --> <!-- MATCHED MATCHED MATCHED -->,
then the times at which it will be evaluated depend on the form.
The following table summarizes at what times evaluation will take
place for any given form seen at top level by the compiler.
<table>
<tr valign='top'><td colspan='2'><font class='lisp'> (eval-when <!-- open: 76, close: 75 --><font class="italic">times-list</font><!-- open: 76, close: 76 --> <!-- MATCHED MATCHED MATCHED --> <!-- open: 77, close: 76 --><font class="italic">form1</font><!-- open: 77, close: 77 --> <!-- MATCHED MATCHED MATCHED --> ...)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td><!-- open: 78, close: 77 --><font class="italic">times-list</font><!-- open: 78, close: 78 --> <!-- MATCHED MATCHED MATCHED -->
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> (declare (special ...)) <!-- open: 79, close: 78 --><font class="main">or</font><!-- open: 79, close: 79 --> <!-- MATCHED MATCHED MATCHED --> (declare (unspecial ...))</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td><!-- open: 80, close: 79 --><font class="lisp">(load compile)</font><!-- open: 80, close: 80 --> <!-- MATCHED MATCHED MATCHED -->
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> (declare <!-- open: 81, close: 80 --><font class="italic">anything-else</font><!-- open: 81, close: 81 --> <!-- MATCHED MATCHED MATCHED -->)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td><!-- open: 82, close: 81 --><font class="lisp">(compile)</font><!-- open: 82, close: 82 --> <!-- MATCHED MATCHED MATCHED -->
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> (special ...) <!-- open: 83, close: 82 --><font class="main">or</font><!-- open: 83, close: 83 --> <!-- MATCHED MATCHED MATCHED --> (unspecial ...)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td><!-- open: 84, close: 83 --><font class="lisp">(load compile eval)</font><!-- open: 84, close: 84 --> <!-- MATCHED MATCHED MATCHED -->
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> (macro ...) <!-- open: 85, close: 84 --><font class="main">or</font><!-- open: 85, close: 85 --> <!-- MATCHED MATCHED MATCHED --> (defstruct ...)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td><!-- open: 86, close: 85 --><font class="lisp">(load compile eval)</font><!-- open: 86, close: 86 --> <!-- MATCHED MATCHED MATCHED -->
</td></tr>
<tr valign='top'>
<td><font class='lisp'> (comment ...)</font></td><td>Ignored
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> (begf ...) <!-- open: 87, close: 86 --><font class="main">or</font><!-- open: 87, close: 87 --> <!-- MATCHED MATCHED MATCHED --> (endf ...)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td>Ignored but may one day put something in the QFASL file.
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> (compiler-let ((<!-- open: 88, close: 87 --><font class="italic">var val</font><!-- open: 88, close: 88 --> <!-- MATCHED MATCHED MATCHED -->) ...) <!-- open: 89, close: 88 --><font class="italic">body</font><!-- open: 89, close: 89 --> <!-- MATCHED MATCHED MATCHED -->...)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td>At <!-- open: 90, close: 89 --><font class="lisp">(compile eval)</font><!-- open: 90, close: 90 --> <!-- MATCHED MATCHED MATCHED --> time, processes the body with the indicated
variable bindings in effect.  Does nothing at <!-- open: 91, close: 90 --><font class="lisp">load</font><!-- open: 91, close: 91 --> <!-- MATCHED MATCHED MATCHED --> time.
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> (local-declare (<!-- open: 92, close: 91 --><font class="italic">decl decl ...</font><!-- open: 92, close: 92 --> <!-- MATCHED MATCHED MATCHED -->) <!-- open: 93, close: 92 --><font class="italic">body</font><!-- open: 93, close: 93 --> <!-- MATCHED MATCHED MATCHED -->...)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td>Processes the <!-- open: 94, close: 93 --><font class="italic">body</font><!-- open: 94, close: 94 --> <!-- MATCHED MATCHED MATCHED --> in its normal fashion, with the indicated
declarations added to the front of the list which is the value
of <!-- open: 95, close: 94 --><font class="lisp">local-declarations</font><!-- open: 95, close: 95 --> <!-- MATCHED MATCHED MATCHED -->.
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> <!-- open: 96, close: 95 --><font class="italic">anything-else</font><!-- open: 96, close: 96 --> <!-- MATCHED MATCHED MATCHED --></font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td><!-- open: 97, close: 96 --><font class="lisp">(load eval)</font><!-- open: 97, close: 97 --> <!-- MATCHED MATCHED MATCHED -->
</td></tr><!-- item_ --></table><!-- end table -->


	Sometimes a macro wants to return more than one form
for the compiler top level to see (and to be evaluated).  The following
facility is provided for such macros.  If a form
<pre class='lisp'>
(progn (quote compile) <!-- open: 98, close: 97 --><font class="italic">form1</font><!-- open: 98, close: 98 --> <!-- MATCHED MATCHED MATCHED --> <!-- open: 99, close: 98 --><font class="italic">form2</font><!-- open: 99, close: 99 --> <!-- MATCHED MATCHED MATCHED --> ...)
</pre>
is seen at the compiler top level, all of the <!-- open: 100, close: 99 --><font class="italic">form</font><!-- open: 100, close: 100 --> <!-- MATCHED MATCHED MATCHED -->s are processed as if they had been at
compiler top level.  (Of course, in the interpreter they
will all be evaluated, and the <!-- open: 101, close: 100 --><font class="lisp">(quote compile)</font><!-- open: 101, close: 101 --> <!-- MATCHED MATCHED MATCHED --> will harmlessly
evaluate to the symbol <!-- open: 102, close: 101 --><font class="lisp">compile</font><!-- open: 102, close: 102 --> <!-- MATCHED MATCHED MATCHED --> and be ignored.)

<div class='defspec' id='eval-when'><font class='exdent'><font class='funcname' id='eval-when'>eval-when</font><font class="italic"> Special Form</font></br></font><!-- end font_exdent -->An <!-- open: 103, close: 102 --><font class="lisp">eval-when</font><!-- open: 103, close: 103 --> <!-- MATCHED MATCHED MATCHED --> form looks like
<pre class='lisp'>
(eval-when <!-- open: 104, close: 103 --><font class="italic">times-list</font><!-- open: 104, close: 104 --> <!-- MATCHED MATCHED MATCHED --> <!-- open: 105, close: 104 --><font class="italic">form1</font><!-- open: 105, close: 105 --> <!-- MATCHED MATCHED MATCHED --> <!-- open: 106, close: 105 --><font class="italic">form2</font><!-- open: 106, close: 106 --> <!-- MATCHED MATCHED MATCHED --> ...)
</pre>
If one of the element of <!-- open: 107, close: 106 --><font class="italic">times-list</font><!-- open: 107, close: 107 --> <!-- MATCHED MATCHED MATCHED --> is the symbol <!-- open: 108, close: 107 --><font class="lisp">eval</font><!-- open: 108, close: 108 --> <!-- MATCHED MATCHED MATCHED -->, then
the <!-- open: 109, close: 108 --><font class="italic">form</font><!-- open: 109, close: 109 --> <!-- MATCHED MATCHED MATCHED -->s are evaluated; otherwise <!-- open: 110, close: 109 --><font class="lisp">eval-when</font><!-- open: 110, close: 110 --> <!-- MATCHED MATCHED MATCHED --> does nothing.

But when seen by the compiler, this special form does the special things described above.
</div>

<div class='defspec' id='declare'><font class='exdent'><font class='funcname' id='declare'>declare</font><font class="italic"> Special Form</font></br></font><!-- end font_exdent --><!-- open: 111, close: 110 --><font class="lisp">declare</font><!-- open: 111, close: 111 --> <!-- MATCHED MATCHED MATCHED --> does nothing, and returns the symbol <!-- open: 112, close: 111 --><font class="lisp">declare</font><!-- open: 112, close: 112 --> <!-- MATCHED MATCHED MATCHED -->.

But when seen by the compiler, this special form does the special things described above.
</div>

<div class='section' id='18.4'>18.4 Compiler Declarations</div>
	This section describes functions meant to be called during
compilation, and variables meant to be set or bound during compilation,
by using <!-- open: 113, close: 112 --><font class="lisp">declare</font><!-- open: 113, close: 113 --> <!-- MATCHED MATCHED MATCHED --> or <!-- open: 114, close: 113 --><font class="lisp">local-declare</font><!-- open: 114, close: 114 --> <!-- MATCHED MATCHED MATCHED -->.

<div class='defspec' id='local-declare'><font class='exdent'><font class='funcname' id='local-declare'>local-declare</font><font class="italic"> Special Form</font></br></font><!-- end font_exdent -->A <!-- open: 115, close: 114 --><font class="lisp">local-declare</font><!-- open: 115, close: 115 --> <!-- MATCHED MATCHED MATCHED --> form looks like
<pre class='lisp'>
(local-declare (<!-- open: 116, close: 115 --><font class="italic">decl1</font><!-- open: 116, close: 116 --> <!-- MATCHED MATCHED MATCHED --> <!-- open: 117, close: 116 --><font class="italic">decl2</font><!-- open: 117, close: 117 --> <!-- MATCHED MATCHED MATCHED --> ...)
   <!-- open: 118, close: 117 --><font class="italic">form1</font><!-- open: 118, close: 118 --> <!-- MATCHED MATCHED MATCHED -->
   <!-- open: 119, close: 118 --><font class="italic">form2</font><!-- open: 119, close: 119 --> <!-- MATCHED MATCHED MATCHED -->
   ...)
</pre>
Each <!-- open: 120, close: 119 --><font class="italic">decl</font><!-- open: 120, close: 120 --> <!-- MATCHED MATCHED MATCHED --> is consed onto the list <!-- open: 121, close: 120 --><font class="lisp">local-declarations</font><!-- open: 121, close: 121 --> <!-- MATCHED MATCHED MATCHED --> while
the <!-- open: 122, close: 121 --><font class="italic">form</font><!-- open: 122, close: 122 --> <!-- MATCHED MATCHED MATCHED -->s are being evaluated (in the interpreter) or compiled
(in the compiler).  There are two uses for this.  First, it can be
used to pass information from outer macros to inner macros.  Secondly,
the compiler will specially interpret certain <!-- open: 123, close: 122 --><font class="italic">decl</font><!-- open: 123, close: 123 --> <!-- MATCHED MATCHED MATCHED -->s as local
declarations, which only apply to the compilations of the <!-- open: 124, close: 123 --><font class="italic">form</font><!-- open: 124, close: 124 --> <!-- MATCHED MATCHED MATCHED -->s.
It understands the following forms:
<table>
<tr valign='top'><td colspan='2'><font class='lisp'> (special <!-- open: 125, close: 124 --><font class="italic">var1 var2 ...</font><!-- open: 125, close: 125 --> <!-- MATCHED MATCHED MATCHED -->)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td>The variables <!-- open: 126, close: 125 --><font class="italic">var1</font><!-- open: 126, close: 126 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 127, close: 126 --><font class="italic">var2</font><!-- open: 127, close: 127 --> <!-- MATCHED MATCHED MATCHED -->, etc. will be treated as special
variables during the compilation of the <!-- open: 128, close: 127 --><font class="italic">form</font><!-- open: 128, close: 128 --> <!-- MATCHED MATCHED MATCHED -->s.
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> (unspecial <!-- open: 129, close: 128 --><font class="italic">var1 var2 ...</font><!-- open: 129, close: 129 --> <!-- MATCHED MATCHED MATCHED -->)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td>The variables <!-- open: 130, close: 129 --><font class="italic">var1</font><!-- open: 130, close: 130 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 131, close: 130 --><font class="italic">var2</font><!-- open: 131, close: 131 --> <!-- MATCHED MATCHED MATCHED -->, etc. will be treated as local
variables during the compilation of the <!-- open: 132, close: 131 --><font class="italic">form</font><!-- open: 132, close: 132 --> <!-- MATCHED MATCHED MATCHED -->s.
</td></tr>
<tr valign='top'><td colspan='2'><font class='lisp'> (macro <!-- open: 133, close: 132 --><font class="italic">name</font><!-- open: 133, close: 133 --> <!-- MATCHED MATCHED MATCHED --> lambda (x) <!-- open: 134, close: 133 --><font class="italic">body</font><!-- open: 134, close: 134 --> <!-- MATCHED MATCHED MATCHED -->)</font></td><td><!-- empty --></td></tr>
<tr><td><!-- empty title --></td><td><!-- open: 135, close: 134 --><font class="italic">name</font><!-- open: 135, close: 135 --> <!-- MATCHED MATCHED MATCHED --> will be defined as a macro during the compilation
of the <!-- open: 136, close: 135 --><font class="italic">form</font><!-- open: 136, close: 136 --> <!-- MATCHED MATCHED MATCHED -->s.  Note that the <!-- open: 137, close: 136 --><font class="lisp">cddr</font><!-- open: 137, close: 137 --> <!-- MATCHED MATCHED MATCHED --> of this item
is a function.
</td></tr><!-- item_ --></table><!-- end table -->

</div>

<div class='defspec' id='special'><font class='exdent'><font class='funcname' id='special'>special</font><font class="italic"> Special Form</font></br></font><!-- end font_exdent --><!-- open: 138, close: 137 --><font class="lisp">(special <!-- open: 139, close: 137 --><font class="italic">var1</font><!-- open: 139, close: 138 --> <!-- open: 140, close: 138 --><font class="italic">var2</font><!-- open: 140, close: 139 --> ...)</font><!-- open: 140, close: 140 --> <!-- MATCHED MATCHED MATCHED --> causes the variables to
be declared to be "special" for the compiler. 
</div>

<div class='defspec' id='unspecial'><font class='exdent'><font class='funcname' id='unspecial'>unspecial</font><font class="italic"> Special Form</font></br></font><!-- end font_exdent --><!-- open: 141, close: 140 --><font class="lisp">(unspecial <!-- open: 142, close: 140 --><font class="italic">var1</font><!-- open: 142, close: 141 --> <!-- open: 143, close: 141 --><font class="italic">var2</font><!-- open: 143, close: 142 --> ...)</font><!-- open: 143, close: 143 --> <!-- MATCHED MATCHED MATCHED --> removes any "special" declarations
of the variables for the compiler.
</div>

The next three declarations are primarily for Maclisp compatibility.

<div class='defspec' id='*expr'><font class='exdent'><font class='funcname' id='*expr'>*expr</font><font class="italic"> Special Form</font></br></font><!-- end font_exdent --><!-- open: 144, close: 143 --><font class="lisp">(*expr <!-- open: 145, close: 143 --><font class="italic">sym1</font><!-- open: 145, close: 144 --> <!-- open: 146, close: 144 --><font class="italic">sym2</font><!-- open: 146, close: 145 --> ...)</font><!-- open: 146, close: 146 --> <!-- MATCHED MATCHED MATCHED --> declares <!-- open: 147, close: 146 --><font class="italic">sym1</font><!-- open: 147, close: 147 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 148, close: 147 --><font class="italic">sym2</font><!-- open: 148, close: 148 --> <!-- MATCHED MATCHED MATCHED -->, etc.
to be names of functions.  In addition it prevents these functions from appearing
in the list of functions referenced but not defined printed at the end of the compilation.
</div>

<div class='defspec' id='*lexpr'><font class='exdent'><font class='funcname' id='*lexpr'>*lexpr</font><font class="italic"> Special Form</font></br></font><!-- end font_exdent --><!-- open: 149, close: 148 --><font class="lisp">(*lexpr <!-- open: 150, close: 148 --><font class="italic">sym1</font><!-- open: 150, close: 149 --> <!-- open: 151, close: 149 --><font class="italic">sym2</font><!-- open: 151, close: 150 --> ...)</font><!-- open: 151, close: 151 --> <!-- MATCHED MATCHED MATCHED --> declares <!-- open: 152, close: 151 --><font class="italic">sym1</font><!-- open: 152, close: 152 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 153, close: 152 --><font class="italic">sym2</font><!-- open: 153, close: 153 --> <!-- MATCHED MATCHED MATCHED -->, etc.
to be names of functions.  In addition it prevents these functions from appearing
in the list of functions referenced but not defined printed at the end of the compilation.
</div>

<div class='defspec' id='*fexpr'><font class='exdent'><font class='funcname' id='*fexpr'>*fexpr</font><font class="italic"> Special Form</font></br></font><!-- end font_exdent --><!-- open: 154, close: 153 --><font class="lisp">(*fexpr <!-- open: 155, close: 153 --><font class="italic">sym1</font><!-- open: 155, close: 154 --> <!-- open: 156, close: 154 --><font class="italic">sym2</font><!-- open: 156, close: 155 --> ...)</font><!-- open: 156, close: 156 --> <!-- MATCHED MATCHED MATCHED --> declares <!-- open: 157, close: 156 --><font class="italic">sym1</font><!-- open: 157, close: 157 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 158, close: 157 --><font class="italic">sym2</font><!-- open: 158, close: 158 --> <!-- MATCHED MATCHED MATCHED -->, etc.
to be names of special forms.  In addition it prevents these names from appearing
in the list of functions referenced but not defined printed at the end of the compilation.
</div>

	There are some advertised variables whose compile-time values affect
the operation of the compiler.  The user may set these variables by
including in his file forms such as
<pre class='lisp'>
(declare (setq open-code-map-switch t))
</pre>

<div class='defvar' id='run-in-maclisp-switch'><font class='exdent'><font class='funcname' id='run-in-maclisp-switch'>run-in-maclisp-switch</font><font class="italic"> Variable</font><br></font><!-- end font_exdent -->If this variable is non-<!-- open: 159, close: 158 --><font class="lisp">nil</font><!-- open: 159, close: 159 --> <!-- MATCHED MATCHED MATCHED -->, the compiler will try to warn the
user about any constructs which will not work in Maclisp.  By no means
will all Lisp machine system functions not built in to Maclisp be
cause for warnings;  only those which could not be written by the user
in Maclisp (for example, <!-- open: 160, close: 159 --><font class="lisp">*catch</font><!-- open: 160, close: 160 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 161, close: 160 --><font class="lisp">make-array</font><!-- open: 161, close: 161 --> <!-- MATCHED MATCHED MATCHED -->,
<!-- open: 162, close: 161 --><font class="lisp">value-cell-location</font><!-- open: 162, close: 162 --> <!-- MATCHED MATCHED MATCHED -->, etc.).  Also, lambda-list keywords such as
<!-- open: 163, close: 162 --><font class="lisp">&amp;optional</font><!-- open: 163, close: 163 --> <!-- MATCHED MATCHED MATCHED --> and initialized <!-- open: 164, close: 163 --><font class="lisp">prog</font><!-- open: 164, close: 164 --> <!-- MATCHED MATCHED MATCHED --> variables will be
mentioned.  This switch also inhibits the warnings for obsolete Maclisp functions.
The default value of this variable is <!-- open: 165, close: 164 --><font class="lisp">nil</font><!-- open: 165, close: 165 --> <!-- MATCHED MATCHED MATCHED -->.
</div>

<div class='defvar' id='obsolete-function-warning-switch'><font class='exdent'><font class='funcname' id='obsolete-function-warning-switch'>obsolete-function-warning-switch</font><font class="italic"> Variable</font><br></font><!-- end font_exdent -->If this variable is non-<!-- open: 166, close: 165 --><font class="lisp">nil</font><!-- open: 166, close: 166 --> <!-- MATCHED MATCHED MATCHED -->, the compiler will try to warn
the user whenever an "obsolete" Maclisp-compatibility function such as
<!-- open: 167, close: 166 --><font class="lisp">maknam</font><!-- open: 167, close: 167 --> <!-- MATCHED MATCHED MATCHED --> or <!-- open: 168, close: 167 --><font class="lisp">samepnamep</font><!-- open: 168, close: 168 --> <!-- MATCHED MATCHED MATCHED --> is used.  The default value is <!-- open: 169, close: 168 --><font class="lisp">t</font><!-- open: 169, close: 169 --> <!-- MATCHED MATCHED MATCHED -->.
</div>

<div class='defvar' id='allow-variables-in-function-position-switch'><font class='exdent'><font class='funcname' id='allow-variables-in-function-position-switch'>allow-variables-in-function-position-switch</font><font class="italic"> Variable</font><br></font><!-- end font_exdent -->If this variable is non-<!-- open: 170, close: 169 --><font class="lisp">nil</font><!-- open: 170, close: 170 --> <!-- MATCHED MATCHED MATCHED -->, the compiler allows the use of
the name of a variable in function position to mean that the
variable's value should be <!-- open: 171, close: 170 --><font class="lisp">funcall</font><!-- open: 171, close: 171 --> <!-- MATCHED MATCHED MATCHED -->'d.  This is for compatibility
with old Maclisp programs.  The default value of this variable is
<!-- open: 172, close: 171 --><font class="lisp">nil</font><!-- open: 172, close: 172 --> <!-- MATCHED MATCHED MATCHED -->.
</div>

<div class='defvar' id='open-code-map-switch'><font class='exdent'><font class='funcname' id='open-code-map-switch'>open-code-map-switch</font><font class="italic"> Variable</font><br></font><!-- end font_exdent -->If this variable is non-<!-- open: 173, close: 172 --><font class="lisp">nil</font><!-- open: 173, close: 173 --> <!-- MATCHED MATCHED MATCHED -->, the compiler will attempt
to produce inline code for the mapping functions (<!-- open: 174, close: 173 --><font class="lisp">mapc</font><!-- open: 174, close: 174 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 175, close: 174 --><font class="lisp">mapcar</font><!-- open: 175, close: 175 --> <!-- MATCHED MATCHED MATCHED -->, etc.,
but not <!-- open: 176, close: 175 --><font class="lisp">mapatoms</font><!-- open: 176, close: 176 --> <!-- MATCHED MATCHED MATCHED -->) if the function being mapped is an anonymous
lambda-expression.  This allows that function to reference
the local variables of the enclosing function without the need for special
declarations.
The generated code is also more efficient.  The default value is T.
</div>

<div class='defvar' id='all-special-switch'><font class='exdent'><font class='funcname' id='all-special-switch'>all-special-switch</font><font class="italic"> Variable</font><br></font><!-- end font_exdent -->If this variable is non-<!-- open: 177, close: 176 --><font class="lisp">nil</font><!-- open: 177, close: 177 --> <!-- MATCHED MATCHED MATCHED -->, the compiler regards all variables
as special, regardless of how they were declared.  This provides full
compatibility with the interpreter at the cost of efficiency.
The default is <!-- open: 178, close: 177 --><font class="lisp">nil</font><!-- open: 178, close: 178 --> <!-- MATCHED MATCHED MATCHED -->.
</div>

<div class='defvar' id='inhibit-style-warnings-switch'><font class='exdent'><font class='funcname' id='inhibit-style-warnings-switch'>inhibit-style-warnings-switch</font><font class="italic"> Variable</font><br></font><!-- end font_exdent -->If this variable is non-<!-- open: 179, close: 178 --><font class="lisp">nil</font><!-- open: 179, close: 179 --> <!-- MATCHED MATCHED MATCHED -->, all compiler style-checking is
turned off.  Style checking is used to issue obsolete function
warnings and won't-run-in-Maclisp warnings, and other sorts of
warnings.  The default value is <!-- open: 180, close: 179 --><font class="lisp">nil</font><!-- open: 180, close: 180 --> <!-- MATCHED MATCHED MATCHED -->.  See also the
<!-- open: 181, close: 180 --><font class="lisp">inhibit-style-warnings</font><!-- open: 181, close: 181 --> <!-- MATCHED MATCHED MATCHED --> macro, which acts on one level only of an
expression.
</div>

<div class='defvar' id='retain-variable-names-switch'><font class='exdent'><font class='funcname' id='retain-variable-names-switch'>retain-variable-names-switch</font><font class="italic"> Variable</font><br></font><!-- end font_exdent -->This controls whether the generated FEFs remember the names of the variables
in the function; such information is useful for debugging
(the <!-- open: 182, close: 181 --><font class="lisp">arglist</font><!-- open: 182, close: 182 --> <!-- MATCHED MATCHED MATCHED --> function uses it, see <font color='red'>LINK:(</font>arglist-fun)), but it increases
the size of the QFASL file and the FEFs created.  The variable
may be any of
<table>
<tr valign='top'>
<td><font class='lisp'> nil</font></td><td>No names are saved.
</td></tr>
<tr valign='top'>
<td><font class='lisp'> args</font></td><td>Names of arguments are saved.
</td></tr>
<tr valign='top'>
<td><font class='lisp'> all</font></td><td>Names of arguments and <!-- open: 183, close: 182 --><font class="lisp">&amp;aux</font><!-- open: 183, close: 183 --> <!-- MATCHED MATCHED MATCHED --> variables are saved.
</td></tr><!-- item_ --></table><!-- end table -->

The default value of this symbol is <!-- open: 184, close: 183 --><font class="lisp">args</font><!-- open: 184, close: 184 --> <!-- MATCHED MATCHED MATCHED -->, and it should usually be
left that way.
</div>

<div class='defmac' id='compiler-let'><font class='exdent'><font class='funcname' id='compiler-let'>compiler-let</font><font class="italic"> Macro</font></br></font><!-- end font_exdent --><!-- open: 185, close: 184 --><font class="lisp">(compiler-let ((<!-- open: 186, close: 184 --><font class="italic">variable value</font><!-- open: 186, close: 185 -->)...) <!-- open: 187, close: 185 --><font class="italic">body</font><!-- open: 187, close: 186 -->...)</font><!-- open: 187, close: 187 --> <!-- MATCHED MATCHED MATCHED -->,
syntactically identical to <!-- open: 188, close: 187 --><font class="lisp">let</font><!-- open: 188, close: 188 --> <!-- MATCHED MATCHED MATCHED -->, allows
compiler switches to be bound locally at compile time, during the
processing of the <!-- open: 189, close: 188 --><font class="italic">body</font><!-- open: 189, close: 189 --> <!-- MATCHED MATCHED MATCHED --> forms.
<pre class='lisp'>
<font class='exdent'>Example:
</font><!-- exdent -->(compiler-let ((open-code-map-switch nil))
          (map (function (lambda (x) ...)) foo))
</pre>
will prevent the compiler from open-coding the <!-- open: 190, close: 189 --><font class="lisp">map</font><!-- open: 190, close: 190 --> <!-- MATCHED MATCHED MATCHED -->.
When interpreted, <!-- open: 191, close: 190 --><font class="lisp">compiler-let</font><!-- open: 191, close: 191 --> <!-- MATCHED MATCHED MATCHED --> is equivalent to <!-- open: 192, close: 191 --><font class="lisp">let</font><!-- open: 192, close: 192 --> <!-- MATCHED MATCHED MATCHED -->.  This
is so that global switches which affect the behavior of macro
expanders can be bound locally.
</div>

<div class='defmac' id='inhibit-style-warnings'><font class='exdent'><font class='funcname' id='inhibit-style-warnings'>inhibit-style-warnings</font><font class="italic"> Macro</font></br></font><!-- end font_exdent --><!-- open: 193, close: 192 --><font class="lisp">(inhibit-style-warnings <!-- open: 194, close: 192 --><font class="italic">form</font><!-- open: 194, close: 193 -->)</font><!-- open: 194, close: 194 --> <!-- MATCHED MATCHED MATCHED -->
prevents the compiler from performing style-checking on the top level
of <!-- open: 195, close: 194 --><font class="italic">form</font><!-- open: 195, close: 195 --> <!-- MATCHED MATCHED MATCHED -->.  Style-checking will still be done on the arguments of <!-- open: 196, close: 195 --><font class="italic">form</font><!-- open: 196, close: 196 --> <!-- MATCHED MATCHED MATCHED -->.
Both obsolete function warnings and won't-run-in-Maclisp warnings are
done by means of the style-checking mechanism, so, for example,
<pre class='lisp'>
(setq bar (inhibit-style-warnings (value-cell-location foo)))
</pre>
will not warn that <!-- open: 197, close: 196 --><font class="lisp">value-cell-location</font><!-- open: 197, close: 197 --> <!-- MATCHED MATCHED MATCHED --> will not work in Maclisp,
but
<pre class='lisp'>
(inhibit-style-warnings (setq bar (value-cell-location foo)))
</pre>
will warn, since <!-- open: 198, close: 197 --><font class="lisp">inhibit-style-warnings</font><!-- open: 198, close: 198 --> <!-- MATCHED MATCHED MATCHED --> applies only to the top
level of the form inside it (in this case, to the <!-- open: 199, close: 198 --><font class="lisp">setq</font><!-- open: 199, close: 199 --> <!-- MATCHED MATCHED MATCHED -->).
</div>

<div class='section' id='18.5'>18.5 Compiler Source-Level Optimizers</div>
The compiler stores optimizers for source code on property lists so as
to make it easy for the user to add them.  An optimizer can be used to
transform code into an equivalent but more efficient form (for
example, <!-- open: 200, close: 199 --><font class="lisp">(eq <!-- open: 201, close: 199 --><font class="italic">obj</font><!-- open: 201, close: 200 --> nil)</font><!-- open: 201, close: 201 --> <!-- MATCHED MATCHED MATCHED --> is transformed into <!-- open: 202, close: 201 --><font class="lisp">(null <!-- open: 203, close: 201 --><font class="italic">obj</font><!-- open: 203, close: 202 -->)</font><!-- open: 203, close: 203 --> <!-- MATCHED MATCHED MATCHED -->,
which can be compiled better).  An optimizer can also be used to
tell the compiler how to compile a special form.  For example,
in the interpreter <!-- open: 204, close: 203 --><font class="lisp">do</font><!-- open: 204, close: 204 --> <!-- MATCHED MATCHED MATCHED --> is a special form, implemented by a function
which takes quoted arguments and calls <!-- open: 205, close: 204 --><font class="lisp">eval</font><!-- open: 205, close: 205 --> <!-- MATCHED MATCHED MATCHED -->.  In the compiler,
<!-- open: 206, close: 205 --><font class="lisp">do</font><!-- open: 206, close: 206 --> <!-- MATCHED MATCHED MATCHED --> is expanded in a macro-like way by an optimizer, into
equivalent Lisp code using <!-- open: 207, close: 206 --><font class="lisp">prog</font><!-- open: 207, close: 207 --> <!-- MATCHED MATCHED MATCHED -->, <!-- open: 208, close: 207 --><font class="lisp">cond</font><!-- open: 208, close: 208 --> <!-- MATCHED MATCHED MATCHED -->, and <!-- open: 209, close: 208 --><font class="lisp">go</font><!-- open: 209, close: 209 --> <!-- MATCHED MATCHED MATCHED -->, which
the compiler understands.

The compiler finds the optimizers to apply to a form by looking for
the <!-- open: 210, close: 209 --><font class="lisp">compiler:optimizers</font><!-- open: 210, close: 210 --> <!-- MATCHED MATCHED MATCHED --> property of the symbol which is the
<!-- open: 211, close: 210 --><font class="lisp">car</font><!-- open: 211, close: 211 --> <!-- MATCHED MATCHED MATCHED --> of the form.  The value of this property should be a list of
optimizers, each of which must be a function of one argument.  The
compiler tries each optimizer in turn, passing the form to be
optimized as the argument.  An optimizer which returns the original
form unchanged (and <!-- open: 212, close: 211 --><font class="lisp">eq</font><!-- open: 212, close: 212 --> <!-- MATCHED MATCHED MATCHED --> to the argument) has "done nothing", and
the next optimizer is tried.  If the optimizer returns anything else,
it has "done something", and the whole process starts over again.
This is somewhat like a Markov algorithm.  Only after all the optimizers
have been tried and have done nothing is an ordinary macro definition
processed.  This is so that the macro definitions, which will be seen
by the interpreter, can be overridden for the compiler by an optimizer.

<div class='section' id='18.6'>18.6 Files that Maclisp Must Compile</div>
Certain programs are intended to be run both in Maclisp and in Lisp
Machine Lisp.  These files need some special conventions.  For example,
such Lisp Machine constructs as <!-- open: 213, close: 212 --><font class="lisp">&amp;aux</font><!-- open: 213, close: 213 --> <!-- MATCHED MATCHED MATCHED --> and <!-- open: 214, close: 213 --><font class="lisp">&amp;optional</font><!-- open: 214, close: 214 --> <!-- MATCHED MATCHED MATCHED --> must not be
used.  In addition, <!-- open: 215, close: 214 --><font class="lisp">eval-when</font><!-- open: 215, close: 215 --> <!-- MATCHED MATCHED MATCHED --> must not be used, since only the Lisp
Machine compiler knows about it.  All <!-- open: 216, close: 215 --><font class="lisp">special</font><!-- open: 216, close: 216 --> <!-- MATCHED MATCHED MATCHED --> declarations must be
enclosed in <!-- open: 217, close: 216 --><font class="lisp">declare</font><!-- open: 217, close: 217 --> <!-- MATCHED MATCHED MATCHED -->s, so that the Maclisp compiler will see them.
It is suggested that you turn on <!-- open: 218, close: 217 --><font class="lisp">run-in-maclisp-switch</font><!-- open: 218, close: 218 --> <!-- MATCHED MATCHED MATCHED -->
in such files, which will warn you about a lot of bugs.

The macro-character combination "#Q" causes the object that
follows it to be visible only when compiling for the Lisp Machine.
The combination "#M" causes the  following object to be visible
only when compiling for Maclisp.  These work only on subexpressions
of the objects in the file, however.  To conditionalize top-level objects,
put the macros <!-- open: 219, close: 218 --><font class="lisp">if-for-lispm</font><!-- open: 219, close: 219 --> <!-- MATCHED MATCHED MATCHED --> and
<!-- open: 220, close: 219 --><font class="lisp">if-for-maclisp</font><!-- open: 220, close: 220 --> <!-- MATCHED MATCHED MATCHED --> around them.  (You can only put these around
a single object.)  The <!-- open: 221, close: 220 --><font class="lisp">if-for-lispm</font><!-- open: 221, close: 221 --> <!-- MATCHED MATCHED MATCHED --> macro turns off <!-- open: 222, close: 221 --><font class="lisp">run-in-maclisp-switch</font><!-- open: 222, close: 222 --> <!-- MATCHED MATCHED MATCHED -->
within its object, preventing spurious warnings from the compiler.
The <!-- open: 223, close: 222 --><font class="lisp">#Q</font><!-- open: 223, close: 223 --> <!-- MATCHED MATCHED MATCHED --> macro-character does not do this, since it can be used
to conditionalize any S-expression, not just a top-level form.

	There are actually three possible cases of compiling: you may
be compiling on the Lisp Machine for the Lisp Machine; you may
be compiling in Maclisp for the Lisp Machine (with :LISPM1;QCMP);
or you may be compiling in Maclisp for Maclisp (with COMPLR).
(You can't compile for Maclisp on the Lisp Machine because there isn't a Lisp
Machine Lisp version of COMPLR.)  To allow a file to detect any
of these conditions it needs to, the following macros are provided:

<div class='defmac' id='if-for-lispm'><font class='exdent'><font class='funcname' id='if-for-lispm'>if-for-lispm</font><font class="italic"> Macro</font></br></font><!-- end font_exdent -->If <!-- open: 224, close: 223 --><font class="lisp">(if-for-lispm <!-- open: 225, close: 223 --><font class="italic">form</font><!-- open: 225, close: 224 -->)</font><!-- open: 225, close: 225 --> <!-- MATCHED MATCHED MATCHED --> is seen at the top level of
the compiler, <!-- open: 226, close: 225 --><font class="italic">form</font><!-- open: 226, close: 226 --> <!-- MATCHED MATCHED MATCHED --> is passed to the compiler top level if
the output of the compiler is a QFASL file intended for the Lisp Machine.
If the Lisp Machine interpreter sees this it will evaluate <!-- open: 227, close: 226 --><font class="italic">form</font><!-- open: 227, close: 227 --> <!-- MATCHED MATCHED MATCHED -->
(the macro expands into <!-- open: 228, close: 227 --><font class="italic">form</font><!-- open: 228, close: 228 --> <!-- MATCHED MATCHED MATCHED -->).
</div>

<div class='defmac' id='if-for-maclisp'><font class='exdent'><font class='funcname' id='if-for-maclisp'>if-for-maclisp</font><font class="italic"> Macro</font></br></font><!-- end font_exdent -->If <!-- open: 229, close: 228 --><font class="lisp">(if-for-maclisp <!-- open: 230, close: 228 --><font class="italic">form</font><!-- open: 230, close: 229 -->)</font><!-- open: 230, close: 230 --> <!-- MATCHED MATCHED MATCHED --> is seen at the top level of
the compiler, <!-- open: 231, close: 230 --><font class="italic">form</font><!-- open: 231, close: 231 --> <!-- MATCHED MATCHED MATCHED --> is passed to the compiler top level if
the output of the compiler is a FASL file intended for Maclisp
(e.g. if the compiler is COMPLR).
If the Lisp Machine interpreter sees this it will ignore it
(the macro expands into <!-- open: 232, close: 231 --><font class="lisp">nil</font><!-- open: 232, close: 232 --> <!-- MATCHED MATCHED MATCHED -->).
</div>

<div class='defmac' id='if-for-maclisp-else-lispm'><font class='exdent'><font class='funcname' id='if-for-maclisp-else-lispm'>if-for-maclisp-else-lispm</font><font class="italic"> Macro</font></br></font><!-- end font_exdent -->If <!-- open: 233, close: 232 --><font class="lisp">(if-for-maclisp-else-lispm <!-- open: 234, close: 232 --><font class="italic">form1</font><!-- open: 234, close: 233 --> <!-- open: 235, close: 233 --><font class="italic">form2</font><!-- open: 235, close: 234 -->)</font><!-- open: 235, close: 235 --> <!-- MATCHED MATCHED MATCHED --> is seen at the top level of
the compiler, <!-- open: 236, close: 235 --><font class="italic">form1</font><!-- open: 236, close: 236 --> <!-- MATCHED MATCHED MATCHED --> is passed to the compiler top level if
the output of the compiler is a FASL file intended for Maclisp;
otherwise <!-- open: 237, close: 236 --><font class="italic">form2</font><!-- open: 237, close: 237 --> <!-- MATCHED MATCHED MATCHED --> is passed to the compiler top level.
</div>

<div class='defmac' id='if-in-lispm'><font class='exdent'><font class='funcname' id='if-in-lispm'>if-in-lispm</font><font class="italic"> Macro</font></br></font><!-- end font_exdent -->On the Lisp Machine, <!-- open: 238, close: 237 --><font class="lisp">(if-in-lispm <!-- open: 239, close: 237 --><font class="italic">form</font><!-- open: 239, close: 238 -->)</font><!-- open: 239, close: 239 --> <!-- MATCHED MATCHED MATCHED --> causes <!-- open: 240, close: 239 --><font class="italic">form</font><!-- open: 240, close: 240 --> <!-- MATCHED MATCHED MATCHED -->
to be evaluated; in Maclisp, <!-- open: 241, close: 240 --><font class="italic">form</font><!-- open: 241, close: 241 --> <!-- MATCHED MATCHED MATCHED --> is ignored.
</div>

<div class='defmac' id='if-in-maclisp'><font class='exdent'><font class='funcname' id='if-in-maclisp'>if-in-maclisp</font><font class="italic"> Macro</font></br></font><!-- end font_exdent -->In Maclisp, <!-- open: 242, close: 241 --><font class="lisp">(if-in-maclisp <!-- open: 243, close: 241 --><font class="italic">form</font><!-- open: 243, close: 242 -->)</font><!-- open: 243, close: 243 --> <!-- MATCHED MATCHED MATCHED --> causes <!-- open: 244, close: 243 --><font class="italic">form</font><!-- open: 244, close: 244 --> <!-- MATCHED MATCHED MATCHED -->
to be evaluated; on the Lisp Machine, <!-- open: 245, close: 244 --><font class="italic">form</font><!-- open: 245, close: 245 --> <!-- MATCHED MATCHED MATCHED --> is ignored.
</div>

	When you have two definitions of one function, one conditionalized
for one machine and one for the other, indent the first "<!-- open: 246, close: 245 --><font class="lisp">(defun</font><!-- open: 246, close: 246 --> <!-- MATCHED MATCHED MATCHED -->"
by one space, and the editor will put both function definitions together
in the same file-section.

	In order to make sure that those macros and macro-characters are
defined when reading the file into the Maclisp compiler, you must
make the file start with a prelude, which will have no effect
when you compile on the real machine.  The prelude can
be found in "AI: LMDOC; .COMPL PRELUD"; this will also define
most of the standard Lisp Machine macros and reader macros in Maclisp, including
<!-- open: 247, close: 246 --><font class="lisp">defmacro</font><!-- open: 247, close: 247 --> <!-- MATCHED MATCHED MATCHED --> and the backquote facility.

	Another useful facility is the form <!-- open: 248, close: 247 --><font class="lisp">(status feature lispm)</font><!-- open: 248, close: 248 --> <!-- MATCHED MATCHED MATCHED -->,
which evaluates to <!-- open: 249, close: 248 --><font class="lisp">t</font><!-- open: 249, close: 249 --> <!-- MATCHED MATCHED MATCHED --> when evaluated on the Lisp machine and to <!-- open: 250, close: 249 --><font class="lisp">nil</font><!-- open: 250, close: 250 --> <!-- MATCHED MATCHED MATCHED -->
when evaluated in Maclisp.
<!-- eof -->
</body>
</html>

